(ns samber.routes.services
  (:require
    [reitit.swagger :as swagger]
    [reitit.swagger-ui :as swagger-ui]
    [reitit.ring.coercion :as coercion]
    [reitit.coercion.spec :as spec-coercion]
    [reitit.ring.middleware.muuntaja :as muuntaja]
    [reitit.ring.middleware.multipart :as multipart]
    [reitit.ring.middleware.parameters :as parameters]
    [samber.middleware.formats :as formats]
    [samber.middleware.exception :as exception]
    [samber.middleware :as middleware]
    [ring.util.http-response :refer :all]
    [clojure.java.io :as io]
    [spec-tools.data-spec :as ds]

    [clojure.tools.logging :as log]
    [samber.services.user.register :as reg-service]
    [samber.services.user.login :as login-service]
    [samber.services.user.sms :as sms-service]
    [samber.services.shop.address :as address-service]

    [samber.routes.questions :as questions]))

(defn service-routes []
  ["/api"
   {:coercion spec-coercion/coercion
    :muuntaja formats/instance
    :swagger {:id ::api}
    :middleware [;; query-params & form-params
                 parameters/parameters-middleware
                 ;; content-negotiation
                 muuntaja/format-negotiate-middleware
                 ;; encoding response body
                 muuntaja/format-response-middleware
                 ;; exception handling
                 exception/exception-middleware
                 ;; decoding request body
                 muuntaja/format-request-middleware
                 ;; coercing response bodys
                 coercion/coerce-response-middleware
                 ;; coercing request parameters
                 coercion/coerce-request-middleware
                 ;; multipart
                 multipart/multipart-middleware]}

   ;; swagger documentation
   ["" {:no-doc true
        :swagger {:info {:title "my-api"
                         :description "https://cljdoc.org/d/metosin/reitit"}}}

    ["/swagger.json"
     {:get (swagger/create-swagger-handler)}]

    ["/api-docs/*"
     {:get (swagger-ui/create-swagger-ui-handler
             {:url "/api/swagger.json"
              :config {:validator-url nil}})}]]

   ["/ping"
    {:get (constantly (ok {:message "pong"}))}]

   ["/address"
    {:swagger {:tags ["adress"]}
     :middleware [middleware/wrap-restricted]}

    ["/list"
     {:get  {:summary "list"
             :responses {200 {:body {:code int? :msg string?, (ds/opt :errors) any?
                                                            , (ds/opt :data) any?}}}
             :handler (fn [{token :identity}]
                        {:status 200
                         :body
                         {:code 0 :msg "success" :data (address-service/address-list (:id token))}})}}]
    ["/new"
     {:post {:summary "new."
             :parameters {:body {:user_name string? :tel_number string? :postal_code string? :province_name string? :city_name string? :county_name string? (ds/opt :is_default) boolean?}}
             :responses {200 {:body {:code int? :msg string?, (ds/opt :errors) any?}}}
             :handler (fn [{{:keys [body]} :parameters token :identity}]
                         (address-service/address-new token body)
                         {:status 200
                          :body
                          {:code 0 :msg "success"}})}}]
    ["/delete/:id"
     {:delete {:summary "delete."
               :parameters {:path {:id integer?}}
               :responses {200 {:body {:code int? :msg string?, (ds/opt :errors) any?}}}
               :handler (fn [{{{:keys [id]} :path} :parameters token :identity}]
                           (address-service/address-delete token id)
                           {:status 200
                            :body
                            {:code 0 :msg "success"}})}}]]

   ["/user"
    {:swagger {:tags ["user"]}}
    ["/sms"
     {:post {:summary "register."
             :parameters {:body {:phone string? (ds/opt :code) string?}}
             :responses {200 {:body {:code int? :msg string?, (ds/opt :errors) any?}}}
             :handler (fn [{{:keys [body]} :parameters}]
                         (log/warn body)
                         (sms-service/send-sms body)
                         {:status 200
                          :body
                          {:code 0 :msg "success"}})}}]
    ["/register"
     {:post {:summary "register."
             :parameters {:body {:username string? :mobile string? :password string? :password-confirmation string? :code string?}}
             :responses {200 {:body {:code int? :msg string?, (ds/opt :errors) any?}}}
             :handler (fn [{{:keys [body]} :parameters}]
                        (reg-service/register body)
                        {:status 200 :body {:code 0 :msg "success"}})}}]
    ["/login"
     {:post {:summary "login."
             :parameters {:body {:username string? :password string?}}
             :responses {200 {:body {:code int? :msg string?, (ds/opt :errors) any?
                                                            , (ds/opt :token) any?}}}
             :handler (fn [{{:keys [body]} :parameters addr :remote-addr}]
                        {:status 200 :body
                         (login-service/login body addr)})}}]]

   ; new route add here
   questions/questions-routes])
